﻿#ifndef UI_REDIRECT //重定向头文件（田老师写的）
#define UI_REDIRECT

#include <iostream>
#include <streambuf>
#include <string>

#include <QPlainTextEdit>

class QRedirectStream : public std::basic_streambuf<char>
{
public:
    QRedirectStream(std::ostream &stream, QPlainTextEdit* text_edit)
        : m_stream(stream)
        , outtype_(0)
    {
        log_window = text_edit;
        m_old_buf = stream.rdbuf();
        stream.rdbuf(this);

        this->context_menu_ = log_window->createStandardContextMenu();
    }
    ~QRedirectStream()
    {
        // output anything that is left
        if (!m_string.empty())
        {
            //        log_window->append(m_string.c_str());
            log_window_append(m_string);
        }

        m_stream.rdbuf(m_old_buf);
    }

    inline void toggle(int outtype = 0) {outtype_ = outtype; }

protected:
    virtual int_type overflow(int_type v)
    {
        if (v == '\n')
        {
            //            log_window->append(m_string.c_str());
            log_window_append(m_string);
            m_string.erase(m_string.begin(), m_string.end());
        }
        else
            m_string += v;

        return v;
    }

    virtual std::streamsize xsputn(const char *p, std::streamsize n)
    {
        m_string.append(p, p + n);

        size_t pos = 0;
        while (pos != std::string::npos)
        {
            pos = m_string.find('\n');
            if (pos != std::string::npos)
            {
                std::string tmp(m_string.begin(), m_string.begin() + pos);
                //                log_window->append(tmp.c_str());
                log_window_append(tmp);
                m_string.erase(m_string.begin(), m_string.begin() + pos + 1);
            }
        }

        return n;
    }

private:

    inline void log_window_append(const std::string& str)
    {
        QString line(QString::fromStdString(str/* + "\n"*/));
        //        line.append(line);
        log_window->appendPlainText(line);

        //        QTextCursor cursor = log_window->textCursor();
        ////        QString alertHtml = "<font color=\"DeepPink\"><b>";
        ////        QString notifyHtml = "<font color=\"#900C3F\"><b>";
        ////        QString infoHtml = "<font color=\"DARKSLATEBLUE\"><b>";
        ////        QString endHtml = "</b></font><br>";

        //        QString alertHtml = "<p style=\"font-family:Courier New; color:RED; font-size: 14px;\"><b>";
        //        QString notifyHtml = "<p style=\"font-family:Courier New; color:#900C3F; font-size: 14px;\"><b>";
        //        QString infoHtml = "<p style=\"font-family:Courier New; color:DARKSLATEBLUE; font-size: 14px;\"><b>";
        //        QString endHtml = "</b></p>";

        //        switch(outtype_)
        //        {
        //            case 2/*msg_alert*/: line = alertHtml   + "[!] " + line + "<br>"; break;
        //            case 1/*msg_notify*/: line = notifyHtml + "[*] " + line + "<br>"; break;
        //            case 0/*msg_info*/: line = infoHtml     + "[I] " + line + "<br>"; break;
        //            default: line = infoHtml + "[INFO]" + line + "<br>"; break;
        //        }

        ////        if (log_window->toPlainText().size() > 5000) {
        ////            log_window->clear();
        ////        }

        //        line = line + endHtml;
        //        log_window->insertHtml(line);
        //        cursor.movePosition(QTextCursor::End);
        //        log_window->setTextCursor(cursor);

    }

    std::ostream &m_stream;
    std::streambuf *m_old_buf;
    std::string m_string;
    QPlainTextEdit* log_window;
    QMenu* context_menu_;

    int outtype_; // 0 - info; 1 - notify;  2 - alert;
};

#endif // UI_REDIRECT

